home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cserial / vt100.c < prev    next >
C/C++ Source or Header  |  1990-04-04  |  22KB  |  1,223 lines

  1. /*
  2.  *                               VT100.C
  3.  *
  4.  *                           Written for the
  5.  *
  6.  *                              Datalight
  7.  *                           Microsoft V 5.x
  8.  *                                TurboC
  9.  *                                  &
  10.  *                               Zortech
  11.  *
  12.  *                             C Compilers
  13.  *
  14.  *            Copyright (c) John Birchfield 1987, 1988, 1989
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <process.h>
  19. #include <ctype.h>
  20. #include "_kb.h"
  21. #include "8250xon.h"
  22. #include "screen.h"
  23. #include "vt100.h"
  24. #if (!defined (TRUE))
  25. #    define TRUE  (1)
  26. #    define FALSE (0)
  27. #endif
  28.  
  29. char Duplex [2]    = { 'F', 0 },
  30.      RubOut [2]    = { 255, 0 },
  31.      BackSpace [2] = { 8,   0 },
  32.      Cmask     [2] = {127,  0 },
  33.      CrLf      [2] = {  0,  0 };
  34.  
  35.  
  36. #if (defined (STANDALONE))
  37. #include "options.h"
  38. void print_screen_header (void);
  39.  
  40. main (argc, argv)
  41. int argc;
  42. char *argv [];
  43. {
  44.     FILE *fp;
  45.     void vt100_driver (), VT100_init ();
  46.     set_options (argc, argv);
  47.     trap_ctrl_break ();
  48.     timer_init ();
  49.     xon8250_init (Port, 4096);
  50.     fputs ("--  VT100 Terminal Emulator --\n", stdout);
  51.     if (Cfg_Str [0])
  52.     {
  53.         xon8250_port_init (Cfg_Str);
  54.         fputs (Opt_Msg, stdout);
  55.     }
  56.     else
  57.     {
  58.         xon8250_port_enable ();
  59.         fputs ("Default Port Settings Used\n", stdout);
  60.     }
  61.     fputs ("Use <Alt>F10 to exit, <Alt>F9 to spawn DOS,"
  62.            " or <Alt>F8 to Send Break\n", stdout);
  63.     screen_init();
  64.     
  65.     print_screen_header ();
  66.     rowcol (23, 0);
  67.     while (xon8250_timed_read (1) != -1)
  68.         ;
  69.     VT100_init ();
  70.     vt100_driver ();
  71.     xon8250_term ((Cfg_Str [0])?1:0);
  72.     timer_term ();
  73.     release_ctrl_break ();
  74. }
  75.  
  76.  
  77.  
  78. void
  79. print_screen_header ()
  80. {
  81.     char save = Scr_ATTR;
  82.     Scr_ATTR = INVERSE;
  83.     rowcol(24,0);
  84.     cleol();
  85.     rowcol (24, 0);
  86.     aputs (INVERSE, "VT100 Emulator");
  87.     Scr_ATTR = save;
  88. }
  89. #endif
  90.  
  91.  
  92.  
  93. /*--------------------------------------------------------------------*
  94.  |               All of the VT100 Specific Stuff Follows              |
  95.  *--------------------------------------------------------------------*/
  96. void    ANSI_MODE (void), CUB (void), CUD (void), CUF (void),
  97.         CUP (void), CUU (void), DA (void), DECSTBM (void), DECSC (void),
  98.         DECALN (void), DECRC (void), DSR (void), ED (void), EL (void),
  99.         RESET (void), RM (void), SGR (void), SM (void), TBC (void),
  100.         escA (void), escB (void), escC (void), escD (void), escE (void),
  101.         escF (void), escG (void), escH (void), escI (void),
  102.         escJ (void), escK (void), escM (void), escY (void), escZ (void);
  103.  
  104. #define    P_MAX         6    /* max no of parameter accumulators */
  105. #define E_BUFF_MAX    11    /* max chars in escape interpreter buffer */
  106.  
  107. static    int        save_row,         save_col,
  108.                 save_attr,        save_crlf,
  109.                 initdone = '\0',
  110.                 tab_stop[80],
  111.                 special_graphics, ansi_mode,
  112.                 appl_mode,        DECKPNM,
  113.                 vt_save_attr,
  114.                 vt_save_row,      vt_save_col,
  115.                 vt_top,              vt_bot,
  116.                 vt_tlim,          vt_blim,
  117.                 vt_row,           vt_col,
  118.                 vt_crlf,          vt_org,
  119.                 vt_wrap,          vt_xoff;
  120.  
  121. char            ansi_cursor_set[]    = "\\eO%c",
  122.                 ansi_cursor_reset[]    = "\\e[%c",
  123.                 vt52_cursor[]        = "\\e%c",
  124.                   vt52_kp[]            = "\\e?%c",
  125.                 ansi_kp[]            = "\\eO%c",
  126.                 *kp_sptr,            *cursor_sptr;
  127.  
  128. void vt_putf(char *,...),
  129.      vtpf_itoa (int),
  130.      vtput_char (char c),
  131.      VT_Put_Scr (char),
  132.      VT100_Cmd (char),
  133.      VT100_KB (char),
  134.      VT100_Out (char);
  135.  
  136. void
  137. vt100_driver () 
  138. {
  139.     int chin, chout;
  140.     do 
  141.     {
  142.         if (!(vt_xoff) && ((chin = xon8250_read ()) != -1))
  143.             if (chin &= *Cmask)
  144.                 VT100_Cmd (chin);
  145.         if ((chout = _kb ()) != -1) 
  146.         {
  147.             switch (chout) 
  148.             {
  149.                 case PF5:
  150.                     tab_stop[vt_col] = TRUE;
  151.                     break;
  152.                 case PF6:
  153.                     tab_stop[vt_col] = FALSE;
  154.                     break;
  155.                 case APF8:
  156.                     xon8250_write_break ();
  157.                     break;
  158.                 case APF9:
  159.                     spawnlp (0, "COMMAND.COM", "COMMAND.COM", (char *) 0);
  160.                     print_screen_header ();
  161.                     vt_row = 23; vt_col = 0;
  162.                     rowcol (vt_row, vt_col);
  163.                     break;
  164.                 case APF10:
  165.                     break;
  166.                 default:
  167.                     if (chout != APF1)
  168.                         VT100_KB (chout);
  169.                     break;
  170.             }
  171.         }
  172.     } while (chout != APF10);
  173. }
  174.  
  175.  
  176.  
  177.  
  178. /*--------------------------- VT100_Cmd () ---------------------------*/
  179. /*
  180.  *
  181.  */
  182. static    int    p_ix          = 0, p_acc [P_MAX] = { 0 };
  183. static char lastchar = '\0';
  184. void
  185. VT100_Cmd (char ch)
  186. {
  187.     if (ch==BS)
  188.     {
  189.         if (vt_col) 
  190.         {
  191.             rowcol (vt_row,--vt_col);
  192.         }
  193.         return;
  194.     }
  195.     if (lastchar && (ch==CAN || ch==SUB))
  196.         goto reset;
  197.     if (ch==DEL)
  198.         return;
  199.  
  200.     switch (lastchar)
  201.     {
  202.         default:
  203.             if (ch==ESC)
  204.             {
  205.                 lastchar = ch;
  206.                 while (p_ix >= 0)
  207.                     p_acc [p_ix--] = 0;
  208.                 p_ix = 0;
  209.                 return;
  210.             }
  211.             VT100_Out (ch);
  212.             return;
  213.         case ESC:
  214.             switch (ch)
  215.             {
  216.                 case ESC: return;
  217.                 case '[':
  218.                 case '(':
  219.                 case ')':
  220.                 case 'Y':
  221.                 case '#': lastchar = ch;   return;
  222.                 case '7': DECSC ();        goto reset;
  223.                 case '8': DECRC ();        goto reset;
  224.                 case '<': ANSI_MODE ();    goto reset;
  225.                 case '>': DECKPNM = FALSE; goto reset;
  226.                 case '=': DECKPNM = TRUE;  goto reset;
  227.                 case 'A': escA  ();        goto reset;
  228.                 case 'B': escB  ();        goto reset;
  229.                 case 'C': escC  ();        goto reset;
  230.                 case 'D': escD  ();        goto reset;
  231.                 case 'E': escE  ();        goto reset;
  232.                 case 'F': escF  ();        goto reset;
  233.                 case 'G': escG  ();        goto reset;
  234.                 case 'H': escH  ();        goto reset;
  235.                 case 'I': escI  ();        goto reset;
  236.                 case 'J': ED ();           goto reset;
  237.                 case 'K': EL ();           goto reset;
  238.                 case 'M': escM  ();        goto reset;
  239.                 case 'Z': escZ  ();        goto reset;
  240.                 case 'c': RESET ();        goto reset;
  241.                 case 'y':                  goto reset;
  242.                 default : VT100_Out (ch);  goto reset;
  243.             }
  244.         case '[':
  245.             switch (ch)
  246.             {
  247.                 case 'A': CUU ();     goto reset;
  248.                 case 'B': CUD ();     goto reset;
  249.                 case 'C': CUF ();     goto reset;
  250.                 case 'D': CUB ();     goto reset;
  251.                 case 'H':
  252.                 case 'f': CUP ();     goto reset;
  253.                 case 'J': ED ();      goto reset;
  254.                 case 'K': EL ();      goto reset;
  255.                 case 'c': DA ();      goto reset;
  256.                 case 'g': TBC ();     goto reset;
  257.                 case 'h': SM ();      goto reset;
  258.                 case 'l': RM ();      goto reset;
  259.                 case 'm': SGR ();     goto reset;
  260.                 case 'n': DSR ();     goto reset;
  261.                 case 'q':             goto reset;
  262.                 case 'r': DECSTBM (); goto reset;
  263.                 case ';': p_ix++;
  264.                 case '?':             return;
  265.                 default:
  266.                     if isdigit (ch)
  267.                     {
  268.                         p_acc [p_ix] *= 10;
  269.                         p_acc [p_ix] += (ch-'0');
  270.                         return;
  271.                     }
  272.                     VT100_Out (ch);
  273.                     goto reset;
  274.             }
  275.         case '(':
  276.         case ')': goto reset;
  277.         case '#':
  278.             if (ch=='8')
  279.                 DECALN ();
  280.             goto reset;
  281.         case 'Y':
  282.             p_acc [p_ix++] = ch - 31;
  283.             if (p_ix < 2)
  284.                 break;
  285.             else
  286.             {
  287.                 CUP ();
  288.                 goto reset;
  289.             }
  290.     }
  291.     return;
  292. reset:
  293.     lastchar = '\0';
  294. }
  295.  
  296.  
  297.  
  298.  
  299. /*--------------------------- VT100_Out () ---------------------------*/
  300. /*
  301.  *
  302.  */
  303. void
  304. VT100_Out (char ch)
  305. {
  306.     switch (ch) 
  307.     {
  308.         case BEL:
  309.             putchar (ch);
  310.             rowcol (vt_row, vt_col);
  311.             break;
  312.         case HT:
  313.             while (vt_col < 79)
  314.                 if (tab_stop[++vt_col])
  315.                     break;
  316.             rowcol(vt_row, vt_col);
  317.             break;
  318.         case DEL:
  319.         case ESC:
  320.             break;
  321.         default:
  322.             VT_Put_Scr (ch);
  323.             break;
  324.     }
  325. }
  326.  
  327.  
  328.  
  329.  
  330. /*------------------------- VT_Put_Scr () -------------------------*/
  331. /*
  332.  *
  333.  */
  334. void
  335. VT_Put_Scr (char ch)
  336. {
  337.     static char vt_wrapped = FALSE;
  338.  
  339.     if (vt_wrapped) 
  340.     {
  341.         if (ch == CR)
  342.             return;
  343.         vt_wrapped = FALSE;
  344.         if (ch == LF)
  345.             return;
  346.     }
  347.     if (vt_row > vt_bot)
  348.     {
  349.         rowcol (vt_row=vt_bot, vt_col);
  350.         scroll_up (1, vt_top, 0, vt_bot, 79);
  351.     }
  352.     switch (ch) 
  353.     {
  354.         case CR:
  355.             vt_col = 0;
  356.             rowcol (vt_row, vt_col);
  357.             if (vt_crlf == FALSE)
  358.                 break;
  359.         case LF:
  360.         case VT:
  361.         case FF:
  362.             if (++vt_row > vt_bot)
  363.                 scroll_up (1, vt_top, 0, vt_row=vt_bot, 79);
  364.             rowcol (vt_row, vt_col);
  365.             break;
  366.         default:
  367.             aput (Scr_ATTR, ch);
  368.             if (++vt_col > 79) 
  369.             {
  370.                 if (!vt_wrap)
  371.                     rowcol (vt_row, --vt_col);
  372.                 else
  373.                 {
  374.                     vt_col = 0;
  375.                     vt_row++;
  376.                     vt_wrapped = TRUE;
  377.                 }
  378.             }
  379.             break;
  380.     }
  381. }
  382.  
  383.  
  384.  
  385.  
  386. /*---------------------------- DECALN () ----------------------------*/
  387. /*
  388.  *
  389.  */
  390. void
  391. DECALN (void)
  392. {
  393.     int i=1920;
  394.     rowcol (0, 0);
  395.     while (i--)
  396.         aput (Scr_ATTR, 'E');
  397.     rowcol (vt_row, vt_col);
  398. }
  399. /*----------------------------- DECSC () -----------------------------*/
  400. /*
  401.  * ESC 7 - Save Cursor  (DEC Private)
  402.  */
  403. void
  404. DECSC (void)
  405. {
  406.     vt_save_row        = vt_row;
  407.     vt_save_col        = vt_col;
  408.     vt_save_attr    = Scr_ATTR;
  409. }
  410.  
  411.  
  412.  
  413.  
  414. /*----------------------------- DECRC () -----------------------------*/
  415. /*
  416.  * ESC 8 - Restore Cursor (DEC Private)
  417.  */
  418. void
  419. DECRC (void)
  420. {
  421.     vt_row        = vt_save_row;
  422.     vt_col        = vt_save_col;
  423.     Scr_ATTR    = vt_save_attr;
  424.     rowcol (vt_row, vt_col);
  425. }
  426.  
  427.  
  428.  
  429.  
  430. /*------------------------------ DSR () ------------------------------*/
  431. /*
  432.  *
  433.  */
  434. void
  435. DSR (void)
  436. {
  437.     switch (p_acc [0])
  438.     {
  439.         case 5:    vt_putf ("\\e[0n");                             break;
  440.         case 6: vt_putf ("\\e[%d;%dR", vt_row + 1, vt_col + 1); break;
  441.         default:                                                break;
  442.     }
  443. }
  444.  
  445.  
  446.  
  447.  
  448. /*--------------------------- ANSI_MODE () ---------------------------*/
  449. /*
  450.  * ESC  < - Enter ANSI Mode
  451.  */
  452. void
  453. ANSI_MODE (void)
  454. {
  455.     ansi_mode = TRUE;
  456.     kp_sptr = ansi_kp;
  457.     cursor_sptr = (appl_mode)? ansi_cursor_set: ansi_cursor_reset;
  458. }
  459.  
  460.  
  461.  
  462.  
  463. /*------------------------------ SGR () ------------------------------*/
  464. /*
  465.  *
  466.  */
  467. void
  468. SGR (void)
  469. {
  470.     char    blink        = FALSE,
  471.             bold        = FALSE,
  472.             underscore    = FALSE,
  473.             reverse        = FALSE;
  474.     int        i;
  475.     for (i = 0; i < P_MAX; i++)
  476.         switch (p_acc[i]) 
  477.         {
  478.             case 1:
  479.                 bold = TRUE;
  480.                 break;
  481.             case 4:
  482.                 underscore = TRUE;
  483.                 break;
  484.             case 5:
  485.                 blink    = TRUE;
  486.                 break;
  487.             case 7:
  488.                 reverse = TRUE;
  489.                 break;
  490.             default:
  491.                 break;
  492.         }
  493.     if (underscore) 
  494.     {
  495.         Scr_ATTR = UNDERLINE;
  496.         if (reverse)
  497.             Scr_ATTR |= INVERSE;
  498.     }
  499.     else if (reverse)
  500.         Scr_ATTR = INVERSE;
  501.     else
  502.         Scr_ATTR = NORMAL;
  503.     if (bold)
  504.         Scr_ATTR |= BRIGHT;
  505.     if (blink)
  506.         Scr_ATTR |= BLINK;
  507. }
  508.  
  509. /*----------------------------- escA () -----------------------------*/
  510. /*
  511.  *
  512.  */
  513. void
  514. escA (void) 
  515. {
  516.     if ((ansi_mode == FALSE) && (vt_row))
  517.         rowcol (--vt_row, vt_col);
  518. }
  519.  
  520.  
  521.  
  522.  
  523. /*----------------------------- escB () -----------------------------*/
  524. /*
  525.  *
  526.  */
  527. void
  528. escB (void) 
  529. {
  530.     if ((ansi_mode == FALSE) && (vt_row < 23))
  531.         rowcol (++vt_row, vt_col);
  532. }
  533.  
  534.  
  535.  
  536.  
  537. /*----------------------------- escC () -----------------------------*/
  538. /*
  539.  *
  540.  */
  541. void
  542. escC (void) 
  543. {
  544.     if ((ansi_mode == FALSE) && (vt_col < 79))
  545.         rowcol (vt_row, ++vt_col);
  546. }
  547.  
  548.  
  549.  
  550.  
  551. /*----------------------------- escD () -----------------------------*/
  552. /*
  553.  *
  554.  */
  555. void
  556. escD (void) 
  557. {
  558.     if (ansi_mode)
  559.         if (vt_row < vt_bot)
  560.             rowcol (++vt_row, vt_col);
  561.         else
  562.             scroll_up (1, vt_top, 0, vt_bot, 79);
  563.     else if (vt_col)
  564.         rowcol (vt_row, --vt_col);
  565. }
  566.  
  567.  
  568.  
  569.  
  570. /*----------------------------- escE () -----------------------------*/
  571. /*
  572.  *
  573.  */
  574. void
  575. escE (void) 
  576. {
  577.     if (ansi_mode) 
  578.     {
  579.         vt_col = 0;
  580.         if (vt_row < vt_bot)
  581.             rowcol (++vt_row, vt_col);
  582.         else 
  583.         {
  584.             scroll_up (1, vt_top, 0, vt_bot, 79);
  585.             rowcol (vt_row, vt_col);
  586.         }
  587.     }
  588. }
  589.  
  590.  
  591.  
  592.  
  593. /*----------------------------- escF () -----------------------------*/
  594. /*
  595.  *
  596.  */
  597. void
  598. escF (void) 
  599. {
  600.     special_graphics = TRUE;
  601. }
  602.  
  603.  
  604.  
  605.  
  606. /*----------------------------- escG () -----------------------------*/
  607. /*
  608.  *
  609.  */
  610. void
  611. escG (void) 
  612. {
  613.     special_graphics = FALSE;
  614. }
  615.  
  616.  
  617.  
  618.  
  619. /*----------------------------- escH () -----------------------------*/
  620. /*
  621.  *
  622.  */
  623. void
  624. escH (void) 
  625. {
  626.     if (ansi_mode) 
  627.     {
  628.         tab_stop [vt_col] = TRUE;
  629.         return;
  630.     }
  631.     vt_row = vt_col = 0;
  632.     rowcol (vt_row, vt_col);
  633. }
  634.  
  635.  
  636.  
  637.  
  638. /*----------------------------- escI () -----------------------------*/
  639. /*
  640.  *
  641.  */
  642. void
  643. escI (void) 
  644. {
  645.     if (ansi_mode == FALSE)
  646.         if (vt_row > vt_top)
  647.             rowcol (--vt_row, vt_col);
  648.         else 
  649.         {
  650.             scroll_dn (1, vt_top, 0, vt_bot, 79);
  651.             rowcol (vt_row, vt_col);
  652.         }
  653. }
  654.  
  655.  
  656.  
  657.  
  658. /*----------------------------- escJ () -----------------------------*/
  659. /*
  660.  *
  661.  */
  662. void
  663. escJ (void) 
  664. {
  665.     if (ansi_mode == FALSE) 
  666.     {
  667.         clrscrn ();
  668.         rowcol (vt_row, vt_col);
  669.     }
  670. }
  671.  
  672.  
  673.  
  674.  
  675. /*----------------------------- escK ()  -----------------------------*/
  676. /*
  677.  *
  678.  */
  679. void
  680. escK (void) 
  681. {
  682.     if (ansi_mode == FALSE)
  683.         scroll_up (0, vt_row, vt_col, vt_row, 79);
  684. }
  685.  
  686.  
  687.  
  688.  
  689. /*----------------------------- escM () -----------------------------*/
  690. /*
  691.  *
  692.  */
  693. void
  694. escM (void) 
  695. {
  696.     if (ansi_mode)
  697.         if (vt_row > vt_top)
  698.             rowcol (--vt_row, vt_col);
  699.         else 
  700.         {
  701.             scroll_dn (1, vt_top, 0, vt_bot, 79);
  702.             rowcol (vt_row, vt_col);
  703.         }
  704. }
  705.  
  706.  
  707.  
  708.  
  709. /*----------------------------- escZ () -----------------------------*/
  710. /*
  711.  *
  712.  */
  713. void
  714. escZ (void)
  715. {
  716.     vt_putf ("\\e/Z");
  717. }
  718.  
  719.  
  720.  
  721.  
  722. /*------------------------------ DA () ------------------------------*/
  723. /*
  724.  *
  725.  */
  726. void
  727. DA (void) 
  728. {
  729.     vt_putf ("\\e[?1;0c");
  730. }
  731.  
  732.  
  733.  
  734.  
  735. /*------------------------------ CUU () ------------------------------*/
  736. /*
  737.  * ESC [ Pn A - Cursor Up
  738.  */
  739. void
  740. CUU (void)
  741. {
  742.     do 
  743.     {
  744.         if (vt_row > vt_tlim)
  745.             rowcol (--vt_row, vt_col);
  746.     } while (--p_acc[0] > 0);
  747. }
  748.  
  749.  
  750.  
  751.  
  752. /*------------------------------ CUD () ------------------------------*/
  753. /*
  754.  * ESC [ Pn B - Cursor Down
  755.  */
  756. void
  757. CUD (void) 
  758. {
  759.     do 
  760.     {
  761.         if (vt_row < vt_blim)
  762.             rowcol (++vt_row, vt_col);
  763.     } while (--p_acc[0] > 0);
  764. }
  765.  
  766.  
  767.  
  768.  
  769. /*------------------------------ CUF () ------------------------------*/
  770. /*
  771.  * ESC [ Pn C - Cursor Forward
  772.  */
  773. void
  774. CUF (void) 
  775. {
  776.     do 
  777.     {
  778.         if (vt_col < 79)
  779.             rowcol (vt_row, ++vt_col);
  780.     } while (--p_acc[0] > 0);
  781. }
  782.  
  783.  
  784.  
  785.  
  786. /*------------------------------ CUB () ------------------------------*/
  787. /*
  788.  * ESC [ Pn D - Cursor Backward
  789.  */
  790. void
  791. CUB (void) 
  792. {
  793.     do 
  794.     {
  795.         if (vt_col)
  796.             rowcol (vt_row, --vt_col);
  797.     } while (--p_acc[0] > 0);
  798. }
  799.  
  800.  
  801.  
  802.  
  803. /*------------------------------ CUP () ------------------------------*/
  804. /*
  805.  * ESC [ Pn ; Pn H - Cursor Position
  806.  *                or
  807.  * ESC [ Pn ; Pn f - Horizontal and Vertical  Position
  808.  */
  809. void
  810. CUP (void)
  811. {
  812.     if (p_acc[0])
  813.         --p_acc[0];
  814.     if (p_acc[1])
  815.         --p_acc[1];
  816.     vt_row = p_acc[0] + vt_tlim; vt_col = p_acc[1];
  817.     vt_row = (vt_row<24)?vt_row:23;
  818.     vt_col = (vt_col<80)?vt_col:79;
  819.     if (vt_row <= vt_blim)
  820.         rowcol (vt_row, vt_col);
  821. }
  822.  
  823.  
  824.  
  825.             
  826. /*------------------------------ ED () ------------------------------*/
  827. /*
  828.  * ESC [ Ps J - Erase in Display
  829.  */
  830. void
  831. ED (void)
  832. {
  833.     int    ch;
  834.     if (vt_row < vt_top || vt_row > vt_bot)
  835.         return;
  836.     switch (p_acc[0]) 
  837.     {
  838.         case 0: /* from current cursor position to end of page */
  839.             scroll_up (0, vt_row, vt_col, vt_row, 79);
  840.             if (vt_row < vt_bot)
  841.                 scroll_up (0, vt_row+1, 0, vt_bot, 79);
  842.             break;
  843.         case 1: /* from start of screen to current position */
  844.             if (vt_row > vt_top)
  845.                 scroll_up (0, vt_top, 0, vt_row-1, 79);
  846.             scroll_up (0, vt_row, 0, vt_row, vt_col);
  847.             break;
  848.         case 2:
  849.             scroll_up (0, vt_top, 0, vt_bot, 79);
  850.             break;
  851.         default:
  852.             break;
  853.     }
  854. }
  855.  
  856.  
  857.  
  858.  
  859. /*------------------------------ EL () ------------------------------*/
  860. /*
  861.  * ESC [ Ps K - Erase In Line
  862.  */
  863. void
  864. EL (void)
  865. {
  866.     int    ch;
  867.     if (vt_row < vt_top || vt_row > vt_bot)
  868.         return;
  869.     switch (p_acc[0]) 
  870.     {
  871.         case 0:
  872.             scroll_up (0, vt_row, vt_col, vt_row, 79);
  873.             break;
  874.         case 1: /* from start of line to current position */
  875.             scroll_up (0, vt_row, 0, vt_row, vt_col);
  876.             break;
  877.         case 2:
  878.             scroll_up (0, vt_row, 0, vt_row, 79);
  879.             break;
  880.         default:
  881.             break;
  882.     }
  883. }
  884.  
  885.  
  886.  
  887.  
  888. /*------------------------------ TBC () ------------------------------*/
  889. /*
  890.  * ESC [ Ps g - Tabulation Clear
  891.  */
  892. void
  893. TBC (void)
  894. {
  895.     int    i;
  896.     if (p_acc[0] == 0)
  897.         tab_stop [vt_col] = FALSE;
  898.     else if (p_acc[0] == 3)
  899.         for (i = 0; i < 80; i++)
  900.             tab_stop [i] = FALSE;
  901. }
  902.  
  903.  
  904.  
  905.  
  906. /*------------------------------ SM () ------------------------------*/
  907. /*
  908.  * ESC [ Ps ; ... ; Ps h - Set Mode
  909.  */
  910. void
  911. SM (void)
  912. {
  913.     int i;
  914.     for (i = 0; i < P_MAX; i++)
  915.         switch (p_acc[i]) 
  916.         {
  917.             case 1:
  918.                 appl_mode = TRUE;
  919.                 cursor_sptr = ansi_cursor_set;
  920.                 break;
  921.             case 5:
  922.                 Scr_ATTR = INVERSE;
  923.                 break;
  924.             case 6:
  925.                 vt_org = TRUE;
  926.                 vt_tlim = vt_row = vt_top;
  927.                 vt_blim = vt_bot;
  928.                 vt_col = 0;
  929.                 rowcol (vt_row, vt_col);
  930.                 break;
  931.             case 7:
  932.                 vt_wrap = TRUE;
  933.                 break;
  934.             case 20:
  935.                 vt_crlf = TRUE;
  936.                 break;
  937.         }
  938. }                
  939.  
  940.  
  941.  
  942.  
  943. /*-------------------------- RM () --------------------------*/
  944. /*
  945.  * ESC [ Ps l - Reset Mode
  946.  */
  947. void
  948. RM (void)
  949. {
  950.     int i;
  951.     for (i = 0; i < P_MAX; i++)
  952.         switch (p_acc[i]) 
  953.         {
  954.             case 1:
  955.                 appl_mode = FALSE;
  956.                 cursor_sptr = ansi_cursor_reset;
  957.                 break;
  958.             case 2:
  959.                 ansi_mode = FALSE;
  960.                 cursor_sptr = vt52_cursor;
  961.                 kp_sptr = vt52_kp;
  962.                 break;
  963.             case 5:
  964.                 Scr_ATTR = NORMAL;
  965.                 break;
  966.             case 6:
  967.                 vt_org = FALSE;
  968.                 vt_row = vt_tlim = 0; vt_col = 0;
  969.                 vt_blim = 23;
  970.                 rowcol (vt_row, vt_col);
  971.                 break;
  972.             case 7:
  973.                 vt_wrap = FALSE;
  974.                 break;
  975.             case 20:
  976.                 vt_crlf = FALSE;
  977.                 break;
  978.         }
  979. }                
  980.  
  981.  
  982.  
  983.  
  984. /*---------------------------- DECSTBM () ----------------------------*/
  985. /*
  986.  *
  987.  */
  988. void
  989. DECSTBM (void)
  990. {
  991.     if (p_acc [0]) p_acc [0]--;
  992.     if (p_acc [1]) p_acc [1]--;
  993.     if (p_acc[1] > p_acc[0]) 
  994.     {
  995.         vt_top = p_acc[0];
  996.         vt_bot = (p_acc[1] < 24) ? p_acc [1]: 23;
  997.         vt_tlim = (vt_org) ? vt_top: 0;
  998.         vt_blim = (vt_org) ? vt_bot: 23;
  999.         vt_row = vt_tlim; vt_col = 0;
  1000.         rowcol (vt_row, vt_col);
  1001.     }
  1002. }
  1003.  
  1004.  
  1005.  
  1006.  
  1007. /*----------------------------- RESET () -----------------------------*/
  1008. /*
  1009.  *
  1010.  */
  1011. void
  1012. RESET (void)
  1013. {
  1014.     int i;
  1015.     appl_mode = DECKPNM = FALSE;
  1016.     ansi_mode = vt_wrap = TRUE;
  1017.     cursor_sptr = ansi_cursor_reset;
  1018.     kp_sptr = ansi_kp;
  1019.     vt_tlim = vt_top = 0;
  1020.     vt_blim = vt_bot = 23;
  1021.     vt_crlf = (*CrLf == 'Y')? 1: 0;
  1022.     vt_xoff = vt_org = FALSE;
  1023.     p_ix = 0;
  1024.     for (i = 0; i < 80; i++)
  1025.         tab_stop[i] = '\0';
  1026.     i = g_rowcol ();
  1027.     vt_row = i / 256; vt_col = i % 256;
  1028.     lastchar = '\0';
  1029. }
  1030.  
  1031.  
  1032.  
  1033.  
  1034. /*-------------------------- VT100_init () --------------------------*/
  1035. /*
  1036.  *
  1037.  */
  1038. void
  1039. VT100_init () 
  1040. {
  1041.     int i;
  1042.     if (initdone == FALSE) 
  1043.     {
  1044.         appl_mode = DECKPNM = FALSE;
  1045.         ansi_mode = vt_wrap = TRUE;
  1046.         cursor_sptr = ansi_cursor_reset;
  1047.         kp_sptr = ansi_kp;
  1048.         vt_tlim = vt_top = 0;
  1049.         vt_blim = vt_bot = 23;
  1050.         vt_crlf = (*CrLf == 'Y')? 1: 0;
  1051.         vt_xoff = vt_org = FALSE;
  1052.         p_ix = 0;
  1053.         for (i = 0; i < 80; i++)
  1054.             tab_stop[i] = '\0';
  1055.         i = g_rowcol ();
  1056.         vt_row = i / 256; vt_col = i % 256;
  1057.         lastchar = '\0';
  1058.         initdone = TRUE;
  1059.     }
  1060.     for (i = 0; i < P_MAX; i++)
  1061.         p_acc[i] = 0;
  1062.     p_ix = 0;
  1063.     rowcol (vt_row, vt_col);
  1064. }
  1065.  
  1066.  
  1067.  
  1068.  
  1069. /*--------------------------- VT100_KB () ---------------------------*/
  1070. /*
  1071.  *
  1072.  */
  1073. void
  1074. VT100_KB (char ch)
  1075. {
  1076.     if ((ch >= PF1) && (ch <= PF4))
  1077.         vt_putf (kp_sptr, ('P' + ch - PF1));
  1078.     else if ((ch >= SPF1) && (ch <= SPF10))
  1079.         if (ch == SPF10)
  1080.             if (DECKPNM)
  1081.                 vt_putf (kp_sptr, 'p');
  1082.             else
  1083.                 vtput_char ('0');
  1084.         else if (DECKPNM)
  1085.             vt_putf (kp_sptr, ('q' + ch - SPF1));
  1086.         else
  1087.             vtput_char (ch - SPF1 + '1');
  1088.     else if ((ch >= UPCHAR) && (ch <= LFCHAR))
  1089.         vt_putf (cursor_sptr, (ch - UPCHAR + 'A'));
  1090.     else
  1091.         switch (ch) 
  1092.         {
  1093.             case PF7:
  1094.                 if (DECKPNM)
  1095.                     vt_putf (kp_sptr, 'm');
  1096.                 else
  1097.                     vtput_char ('-');
  1098.                 break;
  1099.             case PF8:
  1100.                 if (DECKPNM)
  1101.                     vt_putf (kp_sptr, 'l');
  1102.                 else
  1103.                     vtput_char (',');
  1104.                 break;
  1105.             case PF9:
  1106.                 if (DECKPNM)
  1107.                     vt_putf (kp_sptr, 'n');
  1108.                 else
  1109.                     vtput_char ('.');
  1110.                 break;
  1111.             case PF10:
  1112.                 if (DECKPNM)
  1113.                     vt_putf (kp_sptr, 'M');
  1114.                 else
  1115.                     vtput_char (CR);
  1116.                 break;
  1117.             case HCHAR:
  1118.                 vt_putf (cursor_sptr, 'H');
  1119.                 break;
  1120.             case DEL1:
  1121.                 vtput_char (*RubOut);
  1122.                 break;
  1123.             case BS:
  1124.                 vtput_char (*BackSpace);
  1125.                 break;
  1126.             default:
  1127.                 vtput_char (ch);
  1128.                 break;
  1129.         }
  1130. }
  1131.  
  1132.  
  1133.  
  1134. void vt_putf(cp, cv)
  1135. char *cp; int cv;
  1136.  
  1137. {
  1138.     char c;
  1139.     int    *cvp,i;
  1140.  
  1141.     cvp = &cv;
  1142.     while(*cp)
  1143.         switch(c = *cp++) 
  1144.         {
  1145.             case '\\':
  1146.                 vtput_char((c = *cp++) == 'e' ? ESC : c);
  1147.                 break;
  1148.             case '%':
  1149.                 switch (c = *cp++) 
  1150.                 {
  1151.                     case 'c':
  1152.                         vtput_char (*cvp++);
  1153.                         break;
  1154.                     case 'n':
  1155.                         c = *cp++;
  1156.                         while (!xon8250_write_buffer_empty ())
  1157.                             ;
  1158.                         for (i = 1000 * (c - '0'); i > 0; i--)
  1159.                             ;
  1160.                         break;
  1161.                     case 'd':
  1162.                         vtpf_itoa (*cvp++);
  1163.                         break;
  1164.                     default:
  1165.                         break;
  1166.                 }
  1167.                 break;
  1168.             default:
  1169.                 vtput_char(c);
  1170.                 break;
  1171.         }
  1172. }
  1173.  
  1174.  
  1175. void
  1176. vtput_char (char c)
  1177. {
  1178.     int i;
  1179.     if (*Duplex == 'H')
  1180.         VT100_Cmd (c);
  1181.     while (xon8250_write (c) == -1)
  1182.         ;
  1183.     if (c==XOFF)
  1184.         vt_xoff = TRUE;
  1185.     else if (c==XON)
  1186.         vt_xoff = FALSE;
  1187. }
  1188.  
  1189. static    char    vtpf_str [6];
  1190.  
  1191. void    vtpf_itoa (int i)
  1192. {
  1193.     char *cp;
  1194.     cp = vtpf_str;
  1195.     *cp = '\0';
  1196.     i = (i < 0) ? -i: i;
  1197.     while (i) 
  1198.     {
  1199.         *cp++ = (i % 10) + '0';
  1200.         i /= 10;
  1201.     }
  1202.     while (--cp >= vtpf_str) 
  1203.     {
  1204.         if (*Duplex == 'H')
  1205.             VT100_Cmd (*cp);
  1206.         while (xon8250_write (*cp) == -1)
  1207.             ;
  1208.     }
  1209. }
  1210.  
  1211.  
  1212. void
  1213. vt_scrup (int cnt, int tr, int tc, int br, int bc)
  1214. {
  1215.     char sv_atr;
  1216.     sv_atr = Scr_ATTR;
  1217.     if (Scr_ATTR != 0x70 && Scr_ATTR != 0x79)
  1218.         Scr_ATTR = NORMAL;
  1219.     scroll_up (cnt, tr, tc, br, bc);
  1220.     Scr_ATTR = sv_atr;
  1221.  
  1222.